﻿using System;
using System.Linq;
using System.Collections.Generic;

namespace ECommerce
{
	public partial class Ordering : BasePage
	{
		private Service.IOrderService _OrderService;
		private Service.IShoppingCartItemService _ShoppingCartItemService;
		private Service.ICashTicketService _CashTicketService;
		private Service.IProductService _ProductService;
		private Service.IAddressService _AddressService;
		private Service.IPaymentMethodService _PaymentMethodService;
		private Service.IShippingMethodService _ShippingMethodService;
		private Service.ICountryService _CountryService;
		private Service.IStateProvinceService _StateProvinceService;

		private IList<Data.Entity.ShoppingCartItem> _ListShoppingCartItems;

		public IList<Data.Entity.ShoppingCartItem> ListShoppingCartItems
		{
			get
			{
				if (_ListShoppingCartItems != null)
				{
					return _ListShoppingCartItems;
				}

				var user = SiteContext.Current.User;

				if (user == null)
				{
					Server.Transfer("~/Login.aspx");
					return null;
				}

				var userID = (Guid)user.ProviderUserKey;

				if (_ShoppingCartItemService == null)
				{
					_ShoppingCartItemService = new Service.ShoppingCartItemService();
				}

				_ListShoppingCartItems = _ShoppingCartItemService.GetShoppingCartItemByUser(userID);

				return _ListShoppingCartItems;
			}
		}

		protected void Page_Load(object sender, EventArgs e)
		{
			if (SiteContext.Current == null)
			{
				Server.Transfer("~/Login.aspx");
			}

			if (!IsPostBack)
			{
				BindMyCashTicket();
			}
		}

		protected void Page_PreRender(object sender, EventArgs e)
		{
			this.Title = GetLocalResourceString("PageTitle.Ordering");

			this.ButtonGenerateOrder.Text = GetLocalResourceString("Ordering.GererateOrderButton.Text");

			this.LCashTicketTitle.Text = GetLocalResourceString("Ordering.CashTicket.Title");
			this.LOrderRemarkTitle.Text = GetLocalResourceString("Ordering.OrderRemark.Title");
		}

		protected void ButtonGenerateOrder_Click(object sender, EventArgs e)
		{
			if (!this.OrderingShippingControl.CheckShippingAddressHasSelected())
			{
				LabelMassege.Text = GetLocalResourceString("Ordering.Massege.PleaseSelectShippingMethod");
				return;
			}

			if (!CheckoutPaymentMethodControl.CheckPaymentMethodHasSelected())
			{
				LabelMassege.Text = GetLocalResourceString("Ordering.Massege.PleaseSelectPaymentMethod");
				return;
			}

			if (this.OrderingShippingControl.SelecrtedAddressID <= 0)
			{
				LabelMassege.Text = GetLocalResourceString("Ordering.Massege.PleaseSelectShippingAddress");
				return;
			}

			LabelMassege.Text = string.Empty;

			SaveTheOrder();
		}

		private void SaveTheOrder()
		{
			var user = SiteContext.Current.User;

			if (user == null || SiteContext.Current.WorkingLanguage == null)
			{
				Server.Transfer("~/Login.aspx");
				return;
			}

			var userID = (Guid)user.ProviderUserKey;

			var shippingAddressID = this.OrderingShippingControl.SelecrtedAddressID;
			var shippingMethodID = this.OrderingShippingControl.SeletedShippingMethodID;
			var paymentMethodID = this.CheckoutPaymentMethodControl.SelectedPaymentMethodID;

			if(_AddressService == null)
			{
				_AddressService = new Service.AddressService();
			}
			var theShippingAddress = _AddressService.GetTheUserAddresses(userID).Where(e => e.AddressId == shippingAddressID).FirstOrDefault();

			if(_PaymentMethodService == null)
			{
				_PaymentMethodService = new Service.PaymentMethodService();
			}
			var thePaymentMethod = _PaymentMethodService.GetThePaymentMethod(paymentMethodID);

			if(_ShippingMethodService == null)
			{
				_ShippingMethodService = new Service.ShippingMethodService();
			}
			var theShippingMethod = _ShippingMethodService.GetAllShippingMethod().Where(e => e.ShippingMethodID == shippingMethodID).FirstOrDefault();

			var theOrder = new Data.Entity.Order();
			if (_OrderService == null)
			{
				_OrderService = new Service.OrderService();
			}

			if(_CountryService == null)
			{
				_CountryService = new Service.CountryService();
			}
			var theCountry = _CountryService.GetAllCountry().Where(e => e.CountryID == theShippingAddress.CountryID).FirstOrDefault();

			if(_StateProvinceService == null)
			{
				_StateProvinceService = new Service.StateProvinceService();
			}
			var theStateProvince = _StateProvinceService.GetAllStateProvince().Where(e => e.StateProvinceID == theShippingAddress.StateProvinceID).FirstOrDefault();

			var theCity = _StateProvinceService.GetAllCity().Where(e => e.CityID == theShippingAddress.CityID).FirstOrDefault();

			// set the order's shipping address
			theOrder.ShippingAddress1 = theShippingAddress.Address1;
			theOrder.ShippingAddress2 = theShippingAddress.Address2;
			theOrder.ShippingCountryID = theShippingAddress.CountryID;
			theOrder.ShippingCountry = (theCountry != null ? theCountry.Name : string.Empty);
			theOrder.ShippingStateProvinceID = theShippingAddress.StateProvinceID;
			theOrder.ShippingStateProvince = (theStateProvince != null ? theStateProvince.Name : string.Empty);
			theOrder.ShippingCityID = theShippingAddress.CityID;
			theOrder.ShippingCity = (theCity != null ? theCity.CityName : string.Empty);
			theOrder.ShippingCompany = theShippingAddress.Company;
			theOrder.ShippingEmail = theShippingAddress.Email;
			theOrder.ShippingFaxNumber = theShippingAddress.FaxNumber;
			theOrder.ShippingFirstName = theShippingAddress.FirstName;
			theOrder.ShippingLastName = theShippingAddress.LastName;
			theOrder.ShippingMethod = theShippingMethod.Name;
			theOrder.ShippingMethodID = theShippingMethod.ShippingMethodID;
			theOrder.ShippingMobileNumber = theShippingAddress.MobileNumber;
			theOrder.ShippingPhoneNumber = theShippingAddress.PhoneNumber;
			theOrder.ShippingStatusID = (int)Data.Entity.ShippingStatuses.Pending;
			theOrder.ShippingZipPostalCode = theShippingAddress.ZipPostalCode;

			// set the order's user
			var userExt = SiteContext.Current.UserExt;
			theOrder.UserID = userID;
			theOrder.UserIP = SiteContext.Current.IPAddress;
			theOrder.UserLanguageID = (userExt == null ? SiteContext.Current.WorkingLanguage.LanguageId : userExt.LanguageID);
			//theOrder.UserTaxDisplayTypeID

			// set the order's payment method
			theOrder.PaymentMethodID = thePaymentMethod.PaymentMethodID;
			theOrder.PaymentMethodName = thePaymentMethod.Name;
			theOrder.PaymentStatusID = (int)Data.Entity.PaymentStatuses.NoPay;

			theOrder.CreatedOn = DateTime.Now;
			theOrder.Deleted = false;
			theOrder.InvoicingHeader = OrderingInvoicingControl.InvoicingHeader;
			theOrder.InvoicingContent = OrderingInvoicingControl.InvoicingContent;
			theOrder.Remark = TextOrderRemark.Text.Trim();

			var theOrderStatus = (from os in _OrderService.GetAllOrderStatus()
								  where os.OrderStatusNumber.Equals((int)Data.Entity.OrderStatuses.WAIT_BUYER_PAY)
								  select os).FirstOrDefault();

			theOrder.OrderStatusID = theOrderStatus.OrderStatusID;

			decimal cashTicketCost = decimal.Zero;
			Data.Entity.CashTicket theCashTicket = null;

			if (orderingcashticketcontainer.Visible)
			{
				if (DDLCashTickets.SelectedIndex > 0)
				{
					if (_CashTicketService == null)
					{
						_CashTicketService = new Service.CashTicketService();
					}

					theCashTicket = _CashTicketService.GetMyCashTicket(userID).Where(exp => exp.CashTicketID.ToString().Equals(DDLCashTickets.SelectedValue.Trim())).FirstOrDefault();
					cashTicketCost = theCashTicket.Cost;
					theOrder.CashTicketId = theCashTicket.CashTicketID;
				}
			}

			decimal cashTicketLimitTotal = GetTheOrdersCashticketLimit(theOrder.UserLanguageID);

			if (cashTicketLimitTotal < cashTicketCost)
			{
				theOrder.OrderDiscount = cashTicketLimitTotal;
			}
			else
			{
				theOrder.OrderDiscount = cashTicketCost;
			}

			theOrder.OrderTotal = GetTheOrdersTotalPrice(userID) + GetShippingCost(theOrder.ShippingStateProvinceID.Value, theOrder.ShippingMethodID.Value) - theOrder.OrderDiscount;

			theOrder.OrderID = _OrderService.CreateNewOrder(theOrder);

			// save the order and product mappings
			SaveTheOrderAndProductMappings(userID, theOrder.OrderID);

			// add a order note for created
			AddOrderNote_WAIT_BUYER_PAY(theOrder.OrderID, GetLocalResourceString(theOrderStatus.Name));

			Response.Redirect("~/OrderConfirm.aspx?orderid=" + theOrder.OrderID.ToString());
		}

		private void SaveTheOrderAndProductMappings(Guid userID, int theOrderID)
		{
			if (theOrderID <= 0)
			{
				return;
			}

			if (ListShoppingCartItems != null && this.ListShoppingCartItems.Count > 0)
			{
				if (_OrderService == null)
				{
					_OrderService = new Service.OrderService();
				}

				foreach (var cartItem in ListShoppingCartItems)
				{
					var theOrderAndProductMapping = new Data.Entity.Order_Product_Mapping();

					theOrderAndProductMapping.CreatedOn = DateTime.Now;
					theOrderAndProductMapping.OrderID = theOrderID;
					theOrderAndProductMapping.ProductID = cartItem.ProductID;
					theOrderAndProductMapping.Quantity = cartItem.Quantity;
					theOrderAndProductMapping.UpdatedOn = DateTime.Now;

					_OrderService.CreateNewOrderProductMapping(theOrderAndProductMapping);
				}

				if (_ShoppingCartItemService == null)
				{
					_ShoppingCartItemService = new Service.ShoppingCartItemService();
				}

				foreach (var cartItem in ListShoppingCartItems)
				{
					_ShoppingCartItemService.DeleteShoppingCartItem(cartItem.ShoppingCartItemID);
				}
			}
		}

		private decimal GetShippingCost(int stateProvinceID, int shippingMethodID)
		{
			if (stateProvinceID > 0 && shippingMethodID > 0)
			{
				if(_ShippingMethodService == null)
				{
					_ShippingMethodService = new Service.ShippingMethodService();
				}

				var shipping = _ShippingMethodService.GetShippingByStateAndProvinceByProvince(stateProvinceID);

				if (shipping == null)
				{
					return decimal.Zero;
				}

				var cost = (from s in shipping
							where s.ShippingMethodID.Equals(shippingMethodID)
							select s.TransportCosts).FirstOrDefault();
				return cost;
			}
			else
			{
				return decimal.Zero;
			}
		}

		private decimal GetTheOrdersTotalPrice(Guid userID)
		{
			decimal result = decimal.Zero;

			if (ListShoppingCartItems != null && ListShoppingCartItems.Count > 0)
			{
				if (_ProductService == null)
				{
					_ProductService = new Service.ProductService();
				}

				foreach (var shoppingCartItem in ListShoppingCartItems)
				{
					var theProduct = _ProductService.GetProduct(shoppingCartItem.ProductID);

					result += (theProduct.ListPrice.Value * shoppingCartItem.Quantity);
				}
			}

			return result;
		}

		private decimal GetTheOrdersCashticketLimit(int languageID)
		{
			var shoppingCartItems = ListShoppingCartItems;

			if (shoppingCartItems == null)
			{
				return decimal.Zero;
			}

			var productIDs = shoppingCartItems.Select(exp => exp.ProductID);

			if (productIDs == null)
			{
				return decimal.Zero;
			}

			if (_ProductService == null)
			{
				_ProductService = new Service.ProductService();
			}

			var cashTicketLimits = from p in _ProductService.GetProductsByLanguage(languageID)
								   where productIDs.Contains(p.ProductID)
								   select p.CashTicketLimit.GetValueOrDefault();

			if (cashTicketLimits == null)
			{
				return decimal.Zero;
			}

			return cashTicketLimits.Sum();
		}

		private void AddOrderNote_WAIT_BUYER_PAY(int orderID, string note)
		{
			if (orderID <= 0 || string.IsNullOrEmpty(note))
			{
				return;
			}

			if (_OrderService == null)
			{
				_OrderService = new Service.OrderService();
			}

			var theOrderNote = new Data.Entity.OrderNote()
			{
				CreatedOn = DateTime.Now,
				DisplayToUser = true,
				Note = note,
				OrderID = orderID
			};

			_OrderService.CreateNewOrderNote(theOrderNote);
		}

		private void BindMyCashTicket()
		{
			var user = SiteContext.Current.User;

			if (user == null)
			{
				Server.Transfer("~/Login.aspx");
				return;
			}

			var userID = (Guid)user.ProviderUserKey;

			if (_CashTicketService == null)
			{
				_CashTicketService = new Service.CashTicketService();
			}

			var cashTickets = _CashTicketService.GetMyCashTicket(userID);

			if (cashTickets == null)
			{
				orderingcashticketcontainer.Visible = false;

				return;
			}

			var activeCashTickets = cashTickets.Where(exp => exp.IsUsed == 0);

			if (activeCashTickets == null || activeCashTickets.Count() <= 0)
			{
				orderingcashticketcontainer.Visible = false;

				return;
			}

			DDLCashTickets.Items.Clear();

			DDLCashTickets.Items.Add(new System.Web.UI.WebControls.ListItem(GetLocalResourceString("Ordering.CashTicket.Select.Tips"), "0"));

			foreach (var item in activeCashTickets)
			{
				System.Web.UI.WebControls.ListItem lstItem = new System.Web.UI.WebControls.ListItem()
				{
					Text = item.CashTicketNumber + "(" + item.Cost.ToString("c2") + ")",
					Value = item.CashTicketID.ToString()
				};

				DDLCashTickets.Items.Add(lstItem);
			}

			DDLCashTickets.SelectedIndex = 0;
		}
	}
}
